package com.resume.aipeople.controller;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/audio")
@RequiredArgsConstructor
@Slf4j
public class AudioController {

    // 音频数据存储 - 用于存储真实的TTS音频数据
    private static final Map<String, byte[]> AUDIO_STORE = new HashMap<>();
    
    // ASR音频数据存储 - 用于存储上传的语音输入音频
    private static final Map<String, byte[]> ASR_AUDIO_STORE = new HashMap<>();
    
    // 音频文件信息存储
    private static final Map<String, Map<String, Object>> AUDIO_INFO_STORE = new HashMap<>();

    static {
        // 生成一个简单的 MP3 头部字节（模拟）
        byte[] mockMp3Header = {
            (byte) 0xFF, (byte) 0xFB, (byte) 0x90, (byte) 0x00,
            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
        };
        
        // 为常见的音频 ID 创建模拟数据
        AUDIO_STORE.put("852025463.mp3", mockMp3Header);
        AUDIO_STORE.put("default.mp3", mockMp3Header);
    }
    
    /**
     * 静态方法供其他服务保存TTS音频数据
     */
    public static void saveAudioData(String audioId, byte[] audioData) {
        AUDIO_STORE.put(audioId, audioData);
        log.info("保存TTS音频数据: {}, 大小: {} bytes", audioId, audioData.length);
    }
    
    /**
     * 静态方法供其他服务保存ASR音频数据
     */
    public static String saveASRAudioData(MultipartFile audioFile) {
        try {
            // 生成唯一的音频ID
            String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
            String originalFilename = audioFile.getOriginalFilename();
            String extension = originalFilename != null && originalFilename.contains(".") 
                ? originalFilename.substring(originalFilename.lastIndexOf(".")) 
                : ".wav";
            String audioId = "asr_" + timestamp + "_" + System.currentTimeMillis() % 10000 + extension;
            
            // 保存音频数据
            byte[] audioData = audioFile.getBytes();
            ASR_AUDIO_STORE.put(audioId, audioData);
            
            // 保存音频文件信息
            Map<String, Object> audioInfo = new HashMap<>();
            audioInfo.put("originalFilename", originalFilename);
            audioInfo.put("contentType", audioFile.getContentType());
            audioInfo.put("size", audioData.length);
            audioInfo.put("uploadTime", LocalDateTime.now().toString());
            audioInfo.put("format", detectAudioFormat(audioData, audioFile.getContentType()));
            AUDIO_INFO_STORE.put(audioId, audioInfo);
            
            log.info("保存ASR音频数据: {}, 原始文件名: {}, 大小: {} bytes, 格式: {}", 
                    audioId, originalFilename, audioData.length, audioInfo.get("format"));
            
            return audioId;
            
        } catch (IOException e) {
            log.error("保存ASR音频数据失败", e);
            return null;
        }
    }
    
    /**
     * 检测音频格式
     */
    private static String detectAudioFormat(byte[] audioData, String contentType) {
        if (contentType != null) {
            if (contentType.contains("webm")) return "webm";
            if (contentType.contains("wav")) return "wav";
            if (contentType.contains("amr")) return "amr";
            if (contentType.contains("mp3")) return "mp3";
            if (contentType.contains("opus")) return "opus";
        }
        
        // 检查文件头
        if (audioData.length >= 12) {
            if (audioData[0] == 'R' && audioData[1] == 'I' && audioData[2] == 'F' && audioData[3] == 'F' &&
                audioData[8] == 'W' && audioData[9] == 'A' && audioData[10] == 'V' && audioData[11] == 'E') {
                return "wav";
            }
            if (audioData[0] == '#' && audioData[1] == '!' && audioData[2] == 'A' && 
                audioData[3] == 'M' && audioData[4] == 'R') {
                return "amr";
            }
            if (audioData[0] == 0x1A && audioData[1] == 0x45 && audioData[2] == (byte)0xDF && audioData[3] == (byte)0xA3) {
                return "webm";
            }
        }
        
        return "unknown";
    }

    @GetMapping("/tts/{audioId}")
    public ResponseEntity<Resource> getTTSAudio(@PathVariable String audioId) {
        log.info("请求TTS音频文件: {}", audioId);
        
        try {
            // 从音频存储中获取音频数据
            byte[] audioData = AUDIO_STORE.get(audioId);
            
            if (audioData == null) {
                // 如果没有找到，生成一个默认的音频数据
                audioData = generateMockAudioData(audioId);
                AUDIO_STORE.put(audioId, audioData);
            }
            
            ByteArrayResource resource = new ByteArrayResource(audioData);
            
            // 根据文件扩展名确定Content-Type
            MediaType contentType = audioId.endsWith(".wav") ? 
                MediaType.parseMediaType("audio/wav") : 
                MediaType.parseMediaType("audio/mpeg");
            
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + audioId + "\"") // inline 表示在线播放
                    .header(HttpHeaders.CACHE_CONTROL, "public, max-age=3600") // 缓存1小时
                    .header("Accept-Ranges", "bytes") // 支持范围请求，便于音频播放
                    .contentType(contentType)
                    .contentLength(audioData.length)
                    .body(resource);
                    
        } catch (Exception e) {
            log.error("获取TTS音频失败: {}", audioId, e);
            return ResponseEntity.notFound().build();
        }
    }

    @GetMapping("/asr/{audioId}")
    public ResponseEntity<Resource> getASRAudio(@PathVariable String audioId) {
        log.info("请求ASR音频文件: {}", audioId);
        
        try {
            // 从ASR音频存储中获取音频数据
            byte[] audioData = ASR_AUDIO_STORE.get(audioId);
            
            if (audioData == null) {
                log.warn("ASR音频文件不存在: {}", audioId);
                return ResponseEntity.notFound().build();
            }
            
            ByteArrayResource resource = new ByteArrayResource(audioData);
            
            // 获取音频文件信息
            Map<String, Object> audioInfo = AUDIO_INFO_STORE.get(audioId);
            String contentType = "audio/wav"; // 默认
            if (audioInfo != null && audioInfo.get("contentType") != null) {
                contentType = (String) audioInfo.get("contentType");
            }
            
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + audioId + "\"")
                    .header(HttpHeaders.CACHE_CONTROL, "public, max-age=3600")
                    .header("Accept-Ranges", "bytes")
                    .contentType(MediaType.parseMediaType(contentType))
                    .contentLength(audioData.length)
                    .body(resource);
                    
        } catch (Exception e) {
            log.error("获取ASR音频失败: {}", audioId, e);
            return ResponseEntity.notFound().build();
        }
    }
    
    @GetMapping("/asr/info/{audioId}")
    public ResponseEntity<Map<String, Object>> getASRAudioInfo(@PathVariable String audioId) {
        Map<String, Object> audioInfo = AUDIO_INFO_STORE.get(audioId);
        
        if (audioInfo == null) {
            return ResponseEntity.notFound().build();
        }
        
        Map<String, Object> response = new HashMap<>(audioInfo);
        response.put("audioId", audioId);
        response.put("downloadUrl", "/api/audio/asr/" + audioId);
        
        return ResponseEntity.ok(response);
    }
    
    @GetMapping("/asr/list")
    public ResponseEntity<Map<String, Object>> getASRAudioList() {
        Map<String, Object> response = new HashMap<>();
        response.put("total", ASR_AUDIO_STORE.size());
        response.put("audioFiles", AUDIO_INFO_STORE.entrySet().stream()
                .map(entry -> {
                    Map<String, Object> info = new HashMap<>(entry.getValue());
                    info.put("audioId", entry.getKey());
                    info.put("downloadUrl", "/api/audio/asr/" + entry.getKey());
                    return info;
                })
                .sorted((a, b) -> ((String) b.get("uploadTime")).compareTo((String) a.get("uploadTime")))
                .collect(java.util.stream.Collectors.toList()));
        
        return ResponseEntity.ok(response);
    }

    @GetMapping("/asr/upload")
    public ResponseEntity<Map<String, Object>> getUploadInfo() {
        Map<String, Object> info = Map.of(
                "maxSize", "10MB",
                "supportedFormats", new String[]{"mp3", "wav", "m4a", "aac", "webm", "opus"},
                "endpoint", "/api/voice/asr",
                "saveAudio", true,
                "description", "上传的音频文件会自动保存，可通过 /api/audio/asr/list 查看"
        );
        return ResponseEntity.ok(info);
    }

    private byte[] generateMockAudioData(String audioId) {
        log.info("生成模拟音频数据: {}", audioId);
        
        // 生成一个简单的WAV文件，因为WAV格式更简单且浏览器支持更好
        return generateSimpleWAV();
    }
    
    /**
     * 生成一个简单的WAV文件 - 1秒的静音
     */
    private byte[] generateSimpleWAV() {
        try {
            int sampleRate = 8000; // 8kHz
            int duration = 1; // 1秒
            int numSamples = sampleRate * duration;
            
            // WAV文件头 (44字节)
            byte[] header = new byte[44];
            
            // RIFF header
            header[0] = 'R'; header[1] = 'I'; header[2] = 'F'; header[3] = 'F';
            int fileSize = 36 + numSamples;
            header[4] = (byte) (fileSize & 0xff);
            header[5] = (byte) ((fileSize >> 8) & 0xff);
            header[6] = (byte) ((fileSize >> 16) & 0xff);
            header[7] = (byte) ((fileSize >> 24) & 0xff);
            
            // WAVE
            header[8] = 'W'; header[9] = 'A'; header[10] = 'V'; header[11] = 'E';
            
            // fmt chunk
            header[12] = 'f'; header[13] = 'm'; header[14] = 't'; header[15] = ' ';
            header[16] = 16; header[17] = 0; header[18] = 0; header[19] = 0; // fmt chunk size
            header[20] = 1; header[21] = 0; // audio format (PCM)
            header[22] = 1; header[23] = 0; // number of channels (mono)
            header[24] = (byte) (sampleRate & 0xff); header[25] = (byte) ((sampleRate >> 8) & 0xff);
            header[26] = (byte) ((sampleRate >> 16) & 0xff); header[27] = (byte) ((sampleRate >> 24) & 0xff);
            header[28] = (byte) (sampleRate & 0xff); header[29] = (byte) ((sampleRate >> 8) & 0xff);
            header[30] = (byte) ((sampleRate >> 16) & 0xff); header[31] = (byte) ((sampleRate >> 24) & 0xff);
            header[32] = 1; header[33] = 0; // block align
            header[34] = 8; header[35] = 0; // bits per sample
            
            // data chunk
            header[36] = 'd'; header[37] = 'a'; header[38] = 't'; header[39] = 'a';
            header[40] = (byte) (numSamples & 0xff);
            header[41] = (byte) ((numSamples >> 8) & 0xff);
            header[42] = (byte) ((numSamples >> 16) & 0xff);
            header[43] = (byte) ((numSamples >> 24) & 0xff);
            
            // 音频数据 (静音)
            byte[] audioData = new byte[numSamples];
            for (int i = 0; i < numSamples; i++) {
                audioData[i] = (byte) 128; // 8位PCM的中点值（静音）
            }
            
            // 合并头部和数据
            byte[] result = new byte[header.length + audioData.length];
            System.arraycopy(header, 0, result, 0, header.length);
            System.arraycopy(audioData, 0, result, header.length, audioData.length);
            
            return result;
            
        } catch (Exception e) {
            log.error("生成WAV文件失败", e);
            // 如果生成失败，返回最小的有效音频数据
            return new byte[]{
                'R', 'I', 'F', 'F', 36, 0, 0, 0, 'W', 'A', 'V', 'E',
                'f', 'm', 't', ' ', 16, 0, 0, 0, 1, 0, 1, 0,
                (byte) 0x40, 0x1F, 0, 0, (byte) 0x40, 0x1F, 0, 0, 1, 0, 8, 0,
                'd', 'a', 't', 'a', 0, 0, 0, 0
            };
        }
    }
}
